<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // event loop 事件循环
      // 同步 -> 异步（微任务 -> 宏任务）

      setTimeout(() => {
        console.log('第二个')
      }, 1000)
      setTimeout(() => {
        console.log('第一个')
      }, 1000)
      // console.log(1) // 同步

      // setTimeout(() => {
      //   // 宏任务
      //   console.log(2)
      // }, 500)

      // new Promise((resolve, reject) => {
      //   console.log(3) // 同步
      //   // resolve()
      //   reject()
      // })
      //   // 微任务
      //   .then((res) => {
      //     console.log(4)
      //   })
      //   .then((res2) => {
      //     console.log(5)
      //   })
      //   .catch((err) => {
      //     console.log('catch')
      //   })
      //   .finally((a) => {
      //     console.log('finally')
      //   })

      // console.log(6) // 同步

      // setTimeout(() => {
      //   // 宏任务
      //   console.log(7)
      // }, 0)

      // 1 5 6 3 4 5 2
      // 1 5 6 2 3 4 5
      // 1 6 3 4 5 7 2
      // 1 6 7 3 4 5 2
      // 1 6 7 3 4 5 2
      // 1 3 4 5 6 7 2
      /**
       * @name event Loop事件循环
       * 同步
       * 异步 （http 定时器 事件） 异步（微宏）
       * * 微：.then catch finally
       * * 宏：定时器
       */
      // 1 -> 3 -> 6 同步
      // -> 4 -> 5 -> finally-> 微任务
      // 7 -> 2 宏任务(基于时间)

      // -------------------------------------------------
      // -------------------------------------------------
      // -------------------------------------------------
      // -------------------------------------------------
      // -------------------------------------------------
      //

      /*
        第一、javascript 是一门单线程语言
      */
      /*
        第二、异步线程 （第一个和第二个属于互斥线程）
          1. js引擎线程：用于解释执行js代码、用户输入、网络请求等；
          2. GUI渲染线程：绘制用户界面，与JS主线程互斥（因为js可以操作DOM，进而会影响到GUI的渲染结果）；
          3. http异步网络请求线程：处理用户的get、post等请求，等返回结果后将回调函数推入到任务队列；
          4. 定时触发器线程：setInterval、setTimeout等待时间结束后，会把执行函数推入任务队列中；
          5. 浏览器事件处理线程：
      */

      /*
       第三、同步任务和异步任务 （同步任务是栈：后进先出）
      */

      /*
       第四、异步任务中的：宏任务和微任务 （异步任务是队列：先进先出）
          宏任务和微任务分类
      */

      /*
        第五个：async 和 await 
        async/await 会讲异步代码以同步方式输出（会找他同步执行）await 之后，类似于微任务，在微之前执行，会放入队列
      */
      async function async1() {
        console.log('a') // 同2
        const res = await async2()
        console.log('b')
      }

      async function async2() {
        console.log('c') // 同 3
        return 2 //
      }

      console.log('d') // 同步 1

      setTimeout(() => {
        // 入宏 1
        console.log('e')
      }, 0)

      async1().then((res) => {
        console.log('f')
      })

      new Promise((resolve) => {
        console.log('g') // 同4
        resolve()
      }).then(() => {
        console.log('h') // 入微1
      })

      console.log('i')

      /**
       * 输出结果：d a c g i b h f e
       */
    </script>
  </body>
</html>
